package com.yunling.qishi.macaca.utils;
/**
 * 根据excel中定位表达式自动生成po脚本，生成的脚本方置在pageObjects包中
 * @author yunling.he
 *1.读取数据，读取数据时，同属一个页面的元素应该放在一个文件一个位置
 *2.判断下一条数据的页面和当前页面是否相同，不同则开始创建页面对像
 *
 *		（1）方法：判断定位方式，并生成by对像
 *		（2）方法：读取文件夹下所有文件
 *		（2）方法：分捡存储，将同属于一个页面的对像存放在map<map<list>>集合中
 *		（2）生成po主要代码
 *		（2）生成一条元素定位方法
 *		（3）生成所有元素定位方法
 *		（4）生成文件并放在包pageObjects中
 */

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;



import jxl.read.biff.BiffException;

public class CreatePO{
	/**
	 * 默认文件夹为src/main/java/com/yunling/qishi/web/pageObjects
	 */
	private String POpathDirectory="src/main/java/com/yunling/qishi/web/pageObjects";
	private SimpleTools tools=new SimpleTools();
	public CreatePO() {
		// TODO Auto-generated constructor stub
	}
	
	public String getPOpathDirectory() {
		return POpathDirectory;
	}

	
	
	public void setPOpathDirectory(String pOpathDirectory) {
		POpathDirectory = pOpathDirectory;
	}

	//	 *1.读取数据，读取数据时，同属一个页面的元素应该放在一个文件一个位置
//读取文件-对元素按页面分捡存储-读取单个元素-判断定位-生成代码文件-继续生成下一个文件
//	 *2.判断下一条数据的页面和当前页面是否相同，不同则开始创建页面对像
//	 *		（1）方法：判断定位方式，并生成by对像
//	 *		（2）方法：读取文件夹下所有文件
//	 *		（2）方法：分捡存储，将同属于一个页面的对像存放在map<map<list>>集合中
//	 *		（2）生成po主要代码
//	 *		（2）生成一条元素定位方法
//	 *		（3）生成所有元素定位方法
//	 *		（4）生成文件并放在包pageObjects中
	/**
	 * 创建页面对像
	 * @param filepathDiretory  元素定位excel所在文件夹
	 * @throws BiffException
	 * @throws IOException
	 */
	public void createPOs(String filepathDiretory) throws BiffException, IOException{
		File file=new File(filepathDiretory);	
		//读取所有文件保存在一个list中
		List<File> travelFolder = tools.travelFolder(file);
		//开始分拣存储，
		for (File file2 : travelFolder) {
			//将一个excel进行分拣，并保存为map
			Map<String, Set<List<String>>> sorting = sorting(file2);
			//迭代每一个页面容器Set<List<String>>,并将其生成页面
			for(String pageObjectName:sorting.keySet()){
				Set<List<String>> pageObject = sorting.get(pageObjectName);
				//开始生成页面
				createPO(pageObject);
			}
			
			}
		
		}
	
	/**
	 * 创建一个页面
	 * @param pageObject 一个页面元素集合
	 * 1.类名
	 * 2.元素名
	 * 3.
	 * 1.要检测页面是否已存在，但不抛出异常，只输出日志
	 * 
	 */
	private void createPO(Set<List<String>> pageObject){
		BufferedWriter bw = null;
		int i=0;
		String className=null;
		String elementName;
		
		for (List<String> list : pageObject) {
			if(i==0){
				className=tools.classNameFormat(list.get(0));
				File file=new File(POpathDirectory+"/"+className+"PO.java");
				if (!file.exists()) {
					try {
						Log.info("页面对像:"+list.get(0)+"PO.java开始创建");
						//System.out.println("页面对像:"+list.get(0)+".java开始创建");
						file.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				} else {
					file.delete();
					//Log.error("页面对像："+list.get(0)+"重名！");
					Log.info("页面对像:"+list.get(0)+"PO.java已删除");
					//System.out.println("页面对像:"+list.get(0)+".java已删除");
					try {
						Log.info("页面对像:"+list.get(0)+"PO.java开始重创建");
					//	System.out.println("页面对像:"+list.get(0)+".java开始重创建");
						file.createNewFile();
					} catch (IOException e) {
						e.printStackTrace();
					}
				
				}
				try {
					bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8"));
					bw.write("package com.yunling.qishi.web.pageObjects;"+"\r\t");
					bw.write("import java.util.List;"+"\r\t");
					bw.write("import org.openqa.selenium.By;"+"\r\t");
					bw.write("import org.openqa.selenium.WebDriver;"+"\r\t");
					bw.write("import org.openqa.selenium.WebElement;"+"\r\t");
					bw.write("import com.gargoylesoftware.htmlunit.ElementNotFoundException;"+"\r\t");
					bw.write("import com.yunling.qishi.web.utils.Log;"+"\r\t");
					bw.write("\r\t");
					bw.write("public class "+className+"PO{"+"\r\t");
					bw.write("WebDriver driver;"+"\r\t");
					bw.write("/**\r\t* 初始化driver	 \r\t* @param driver	\r\t */"+"\r\t");
					bw.write("public "+className+"PO(WebDriver driver) {\r\t");
					bw.write("this.driver=driver;"+"\r\t");
					bw.write("}"+"\r\t");
					bw.write("/**\r\t* 获取driver	 \r\t* @return	\r\t */"+"\r\t");
					bw.write("public WebDriver getDriver() {"+"\r\t");
					bw.write("return this.driver;"+"\r\t");
					bw.write("}"+"\r\t");
				
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			i++;
			try {
				
				elementName=tools.classNameFormat(list.get(1));
				if (list.get(4)==null||list.get(4).equals("0")||list.get(4)=="") {//生成element
					bw.write("/**\r\t* 获取元素:"+elementName+"\r\t* @return */"+"\r\t");
					bw.write("public WebElement get"+elementName+"(){"+"\r\t");
					bw.write("try{"+"\r\t");
					bw.write("WebElement element = driver.findElement("+getLocator(list)+");"+"\r\t");
					bw.write("return element;"+"\r\t");
					bw.write("}catch (ElementNotFoundException e) {"+"\r\t");
					bw.write("Log.error(\"未发现元素:"+elementName+"\");"+"\r\t");
					bw.write("e.printStackTrace();"+"\r\t");
					bw.write("}"+"\r\t");
					bw.write("return null;"+"\r\t");
					bw.write("}"+"\r\t");
					bw.write(""+"\r\t");
					
					
				} else if (Integer.valueOf(list.get(4))==1) {
					bw.write("/**\r\t* 获取元素组:"+elementName+"\r\t* @return */"+"\r\t");
					bw.write("public List<WebElement> get"+elementName+"s(){"+"\r\t");
					bw.write("try{"+"\r\t");
					bw.write("List<WebElement> element = driver.findElements("+getLocator(list)+");"+"\r\t");
					bw.write("return element;"+"\r\t");
					bw.write("}catch (ElementNotFoundException e) {"+"\r\t");
					bw.write("Log.error(\"未发现此元素组:"+elementName+"\");"+"\r\t");
					bw.write("e.printStackTrace();"+"\r\t");
					bw.write("}"+"\r\t");
					bw.write("return null;"+"\r\t");
					bw.write("}"+"\r\t");
					bw.write(""+"\r\t");
				} {//生成elements

				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			bw.write("}"+"\r\t");
			bw.flush();
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Log.info("页面创建成功："+className);
		System.out.println("页面创建成功："+className);
	}
	/**
	 * 根据页面名字创建页面
	 * 要检测是否已存在
	 * @param filePath  excel文件地址
	 * @param pageNames 页面名
	 * @throws IOException 
	 * @throws BiffException 
	 */
	 
	public void createPOs(String filePath,String...pageNames) throws BiffException, IOException{
		String pageNamePath;
		Map<String, Set<List<String>>> sorting = sorting(new File(filePath));
		for (String pageName : pageNames) {
			pageNamePath=POpathDirectory+"/"+tools.classNameFormat(pageName)+".java";
			File file=new File(pageNamePath);
			if (file.exists()) {
				Log.error("此页面已存在"+pageNamePath+",文件创建失败");
				System.out.println("此页面已存在"+pageNamePath+",文件创建失败");
				continue;
			}
			file.createNewFile();
			Set<List<String>> pageObject= sorting.get(pageName);
			createPO(pageObject);
				
			
		}
		
	}
	/**
	 * 修改已有的页面
	 * 要检测是否已存在
	 * @throws IOException 
	 * @throws BiffException 
	 */
	public void changePOs(String filePath,String...pageNames) throws BiffException, IOException{
		String pageNamePath;
		Map<String, Set<List<String>>> sorting = sorting(new File(filePath));
		for (String pageName : pageNames) {
			pageNamePath=POpathDirectory+"/"+tools.classNameFormat(pageName)+".java";
			File file=new File(pageNamePath);
			if (!file.exists()) {
				Log.error("此页面不存在"+pageNamePath+",文件修改失败");
				System.out.println("此页面不存在"+pageNamePath+",文件修改失败");
				continue;
			}
			
			Set<List<String>> pageObject= sorting.get(pageName);
			createPO(pageObject);
			
		}
	}
	
	
	/**
	 * 判断每一条元素定位信息的定位方法和定位代码，并返回定位String对像,
	 * @param list
	 * @return
	 */
	private String getLocator(List<String> list){
		String locatorMethod=list.get(2);//获取定位方法
		String locatorCode=list.get(3);//获取定位代码
		if(locatorMethod.toLowerCase().equals("id")){
			return new String("By.id(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("linktext")) {
			return new String("By.linkText(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("partiallinktext")) {
			return new String("By.partialLinkText(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("name")) {
			return new String("By.name(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("tagname")) {
			return new String("By.tagName(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("xpath")) {
			return new String("By.xpath(\""+locatorCode+"\")");
		}else if (locatorMethod.toLowerCase().equals("cssselector")||
				locatorMethod.toLowerCase().equals("css")) {
			return new String("By.cssSelector(\""+locatorCode+"\")");	
		}else{
			Log.error("元素定位名不正确");
			return null;
		}

	}
	
	
	/**
	 * 对一个excel文件进行分拣
	 * @param file 为分拣对像的文件
	 * @return Map<String, Set<List<String>>>  用于分拣String为页面名，Set为元素信息集合，list<String>为每一条元素信息
	 * @throws BiffException
	 * @throws IOException
	 */
	
	private Map<String, Set<List<String>>> sorting(File file) throws BiffException, IOException{
		ExcelUtil excelUtil;
		List<List<String>> readAll;
		List<String> list;
	
		//开始分拣存储，
		//用于分拣String为页面名，Set为元素信息集合，list<String>为每一条元素信息
		Map<String,Set<List<String>> > pageObjects=new HashMap<>();;
		Set<List<String>> pageObject=new HashSet<>();
		//读取文件中的内容
		excelUtil = new ExcelUtil(file.getAbsolutePath());
		readAll = excelUtil.readAll();//行数据  。列数据
		//将文件中的内容进行分拣存储
		for (int i=0;i<readAll.size();i++) {
			//代表每一行数据
			list = readAll.get(i);
			int size = readAll.size();
			//判断是页面名字是否正确,只由数字英文下划线组成
			if (!tools.isRightName(list.get(0))) {
			//	Log.error("页面名字命名错误，只能由数字英文下划线组成，且不能以数字开头"+list.get(0));
				//System.out.println("页面名字命名错误，只能由数字英文下划线组成，且不能以数字开头"+list.get(0));
				continue;
			}
			
			if (!pageObjects.containsKey(list.get(0))) {
				pageObject.add(list);
			}else{
				Log.error("此文件名"+list.get(0)+"已存在");
				continue;
			}
			
			if(i==size-1){
				//重新初始化pageObject，用于存储下一个pageObject信息,同时将当前这一条信息加入
				pageObjects.put(list.get(0),pageObject);
				pageObject=new HashSet<>();//需要注意重置的位置，只有将页面加入到map中才能重置
			}
			if(i<size-1)
				if (!(list.get(0).equals(readAll.get(i+1).get(0)))) {
					
					//重新初始化pageObject，用于存储下一个pageObject信息,同时将当前这一条信息加入
					pageObjects.put(list.get(0),pageObject);
					pageObject=new HashSet<>();
				}

			
		}
		return pageObjects;
	}
/*public static void main(String[] args) throws BiffException, IOException {
		CreatePO createPO=new CreatePO();
		File file=new File("h:/locate.xls");
		Map<String, Set<List<String>>> sorting = createPO.sorting(file);
		Set<String> keySet = sorting.keySet();
		for (String string : keySet) {
			
			System.out.println(string);
		}
	}*/

}
